#include-once #include "corz_essentials.au3" #include #cs corz color functions v0.4 miscellaneous functions for manipulating colors and their values (c) cor + corz.org 2007->tomorrow! function list.. ConvertColorValue( string{RGB hex color value}, string{output mode} [, boolean{add prefix=false} [, GUI-bool{lower-case]]}) RGBToCMYK( string{hex rgb color[, bool{normalize to percentage}]) RGBToHSL( string{hex rgb color)[, int{index to return}]) RegColorToRGBHexColor() ; standard UDF (Color.au3) functions.. GetColorRed($nColor) GetColorGreen($nColor) GetColorBlue($nColor) ColorChooser(array {Custom Colors}, HWND {Ownder}) #ce ; ; ConvertColorValue() ; ; Accepts a standard RGB hex color value, returns something else. ; This does not convert colors, it converts color *values* .. ; ; Available modes (values are case-insensitive).. ; ; Web RGB Hex use: nothing (if no prefix is required), else use: "Web Hex", "Web", "Hex", or "w" ; AutoIt: use: "Autoit RGB Hex", "Autoit RGB", "AutoIt Hex", "AutoIt", or "a" ; AutoIt GBR: use: "Autoit BGR Hex", "Autoit BGR", "BGR Hex", or "bgr", or "b" ; Visual C++: use: "Visual C++ Hex", "Visual C++ BGR", "Visual C++", "Visual C++ BGR Hex", "C++", or "vc" ; Delphi: use: "Delphi", "Delphi hex", or "d" ; RGB Integer: use: "RGB Integer", "RGB Int", "int", or "i" ; RGB Float: use: "RGB Float", "float", or "f" ; Hue/Sat/Lum: use: "Hue/Sat/Lum", "HSL", or "h" ; CMYK: use: "cmyk", or "k" ; ; If no mode, or an incorrect mode is specified, ConvertColorValue() returns ; the original plain RGB hex value ; ; The third (optional) paramterer is the prefix, defaults to false. ; If set to true, the standard prefix, where applicable, is added to the ; output. eg, FF00FF becomes #FFOOFF. Currently only web hex and Delphi ; formats have a prefix. You can also use a checkbox boolean value for the ; prefix parameter. In other words, you can send a 4 for false. ; ; There is a special usage of the prefix option; if you request a CMYK value, ; and specify a prefix, you get the value "normalized", that is, re-scaled to ; percentages, which is a commonly found CMYK format. ; ; The optional fourth parameter ($index) only works when retrieving decimal ; (integer) color values ("i") You can supply the color index you wish to ; retrieve; 1=red value, 2=green value, 3=blue value. ; ; To retrieve individual HSL values, use RGBToHSL() directly (see below). ; ; ConvertColorValue() Returns a ready-to-use string (or integer, depending) ; of the required color value. Decimal, Float, CMYK, and HSL values are ; delimited by a comma, e.g. "124,90,64" (HSL: Hue:0-360,Sat:0-100,Lum: 0-100) ; ; If you want a color for use in dll calls, the Visual C++ value is the one ; you want (use "vc", or "v") ; ; The 5th parameter is Case. $ON = lower case, $OFF = UPPER CASE. ; func ConvertColorValue($color, $mode="web", $prefix=false, $index=0, $lowercase=$OFF) if StringLeft($color, 1) = "#" then $color = StringTrimLeft($color, 1) $pre = "" switch $mode ; the more long-winded options enable us to easily use human-readable names in the code ; utilizing the text of the menu options directly.. case "i", "RGB Integer", "RGB Int", "int" switch $index case 0 $color = Dec(StringLeft($color, 2)) & "," & Dec(StringMid($color, 3, 2)) & "," & Dec(StringRight($color, 2)) case 1 return Dec(StringLeft($color, 2)) case 2 return Dec(StringMid($color, 3, 2)) case 3 return Dec(StringRight($color, 2)) endswitch case "a", "Autoit RGB Hex", "Autoit RGB", "AutoIt Hex", "AutoIt" $color = '0x' & $color case "b", "Autoit BGR Hex", "Autoit BGR", "BGR Hex", "bgr" $color = '0x' & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2) case "d", "Delphi", "Delphi Hex" $color = "00" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2) $pre = "$" case "v", "vc", "Visual C++ Hex", "Visual C++ BGR", "Visual C++", "Visual C++ BGR Hex", "C++" $color = "0x00" & StringRight($color, 2) & StringMid($color, 3, 2) & StringLeft($color, 2) case "RGB Float", "float", "f" $r = Round((1/255) * Dec(StringLeft($color, 2)), 2) $g = Round((1/255) * Dec(StringMid($color, 3, 2)), 2) $b = Round((1/255) * Dec(StringRight($color, 2)),2) $color = StringFormat("%#.2f", $r) & "," & StringFormat("%#.2f", $g) & "," & StringFormat("%#.2f", $b) case "h", "Hue/Sat/Lum", "HSL", "h/s/l" $color = RGBToHSL($color, ",", 100) case "k", "cmyk", "c/m/y/k" if $prefix = 1 then $color = RGBToCMYK($color, true) else $color = RGBToCMYK($color) endif case "w", "Web Hex", "Web", "Hex" $pre = "#" endswitch if not $prefix or $prefix = 4 then $pre = "" if $lowercase = $ON then $color = StringLower($color) return $pre & $color endfunc ; ; RGBToCMYK() ; ; Very simple calculations. Basically, rgb is "additive" color, and ; CMYK is "subtractive", in other words, with CMYK, you start with ; white, and work up to black (paper) substracting brightness; and ; with rgb, you start with black, and work up to white (peecee monitor), ; adding brightness. So it's the same, but backwards. You could do it ; on your fingers. ; ; Set the optional second paramter to True get the values "normalized", ; that is, re-scaled to percentages, which is a commonly found CMYK format. ; ; Returns a comma-delimited string; "c,m,y,k", e.g. "0.761,0.08,0,0.016" ; By the way, that same value "normalized", is.. "76.1,8,0,1.6" ; func RGBToCMYK($rgb_color, $norm=0) ; get decimal rgb values and scale to 0-1.. $rc_r = ConvertColorValue($rgb_color, "i", 0, 1) / 255 $rc_g = ConvertColorValue($rgb_color, "i", 0, 2) / 255 $rc_b = ConvertColorValue($rgb_color, "i", 0, 3) / 255 $k = MinMin(1-$rc_r, 1-$rc_g, 1-$rc_b) $c = (1 - $rc_r - $k) / ( 1 - $k) $m = (1 - $rc_g - $k) / ( 1 - $k) $y = (1 - $rc_b - $k) / ( 1 - $k) if $norm then return Round($c * 100, 1) & "," & Round($m * 100, 1) & "," & Round($y * 100, 1) & "," & Round($k * 100, 1) else return Round($c, 3) & "," & Round($m, 3) & "," & Round($y, 3) & "," & Round($k, 3) endif endfunc ; ; RGBToHSL() ; ; Calculate an HSL color from an RGB color ; ; Returns a 4-element AutoIt array with element zero being the total (3) ; and the three HSL integer values.. ; ; [3, Hue (0-360 degrees), Saturation (0-1), Luminance/Lightness (0-1)] ; ; You can also specify an optional second paramter; index, being either ; 1, 2, or 3, to return ONLY Hue, Saturation, or Lightness, respectively. ; ; If you specify an index, the return value will be a single float/integer. ; ; There is also a special usage for index, which gets you back the HSL ; as a string, delimited by whatever character you set as the index value. ; ; HSL values come in all sorts of weird scales, sometimes percentages, ; sometimes 0-240, or 0-255, and others. You can deal with that at your end; or ; else feed RGBToHSL the optional third parameter, which automatically multiplies ; the Saturation and Lightness by whatever you like. 100 is common. Hue values ; are always returned in degrees, though it would be easy enough to hack that. ; ; Usage. ; ; To retrieve the HSL as an AutoIt array.. ; ; $color_array = RGBToHSL($my_hex_color) ; ; To retrieve the Lightness of an RGB Hex value.. ; ; $lightness = RGBToHSL($my_hex_color, 3) ; ; To get back the HSL as a comma-delimited string.. ; ; RGBToHSL("650003", ",") [ returns: "358,1.0,0.2" - a dark brown] ; ; func RGBToHSL($rgb_color, $idx="", $simple_array=false, $hsl_scale=1) $rh_r = ConvertColorValue($rgb_color, "i", 0, 1) / 255 $rh_g = ConvertColorValue($rgb_color, "i", 0, 2) / 255 $rh_b = ConvertColorValue($rgb_color, "i", 0, 3) / 255 $rh_min = MinMin($rh_r, $rh_g, $rh_b) $rh_max = MaxMax($rh_r, $rh_g, $rh_b) $rh_delta = $rh_max - $rh_min if $idx <> 1 then ; every little helps ; not perfect, this, but it's the standard method.. $rh_lightness = ($rh_min + $rh_max) / 2 if $idx = 3 then return Round($rh_lightness*$hsl_scale, 2) $rh_saturation = 0 if $rh_lightness > 0 and $rh_lightness < 1 then if $rh_lightness < 0.5 then $rh_saturation = $rh_delta / (2 * $rh_lightness) else $rh_saturation = $rh_delta / (2 - 2 * $rh_lightness) endif endif if $idx = 2 then return Round($rh_saturation*$hsl_scale, 2) endif $rh_hue = 0 if $rh_delta > 0 then if $rh_max = $rh_r and $rh_max <> $rh_g then $rh_hue += ($rh_g - $rh_b) / $rh_delta endif if $rh_max = $rh_g and $rh_max <> $rh_b then $rh_hue += 2 + ($rh_b - $rh_r) / $rh_delta endif if $rh_max = $rh_b and $rh_max <> $rh_r then $rh_hue += 4 + ($rh_r - $rh_g) / $rh_delta endif $rh_hue *= 60 endif if $rh_hue < 0 then $rh_hue += 360 ; hack if $idx = 1 then return Round($rh_hue) $do_string = true if not $idx then $idx = "," $do_string = false endif local $hsl_arr[3] $hsl_arr[0] = Round($rh_hue) $hsl_arr[1] = Round($rh_saturation*$hsl_scale, 2) $hsl_arr[2] = Round($rh_lightness*$hsl_scale, 2) $hsl = $hsl_arr[0] & $idx & $hsl_arr[1] & $idx & $hsl_arr[2] if $do_string then return $hsl if $simple_array then return $hsl_arr return StringSplit($hsl, $idx) endfunc ; convert windows registry color to RGB Hex.. ; func RegColorToRGBHexColor($RegVal) $col = StringSplit($RegVal, " ") if $col[0] < 2 then return "" return Hex($col[1], 2) & Hex($col[2], 2) & Hex($col[3], 2) endfunc ; returns an array with three elements (R, G, B) func ConvertRGBtoDecArray($color) local $c_arr[3] $c_arr[0] = Dec(StringLeft($color, 2)) $c_arr[1] = Dec(StringMid ($color, 3 , 2)) $c_arr[2] = Dec(StringRight($color, 2)) return $c_arr endfunc ; I have other color conversion functions ;o) ; The standard AutoIt UDF color functions ; re-named and here for convenience ; Func GetColorRed($nColor) Return BitAND(BitShift($nColor, 16), 0xff) EndFunc Func GetColorGreen($nColor) Return BitAND(BitShift($nColor, 8), 0xff) EndFunc Func GetColorBlue($nColor) Return BitAND($nColor, 0xff) EndFunc ; ColorChooser() By Cor ; ; An alternative version of the system color chooser dialog function. ; This version can store and retrieve the 16 custom colors. Nifty. ; ; Send an array of 17 AutoIt RGB (e.g. 0xF0EBC3) colors, the first $array[0] being the ; color you wish to initially set in the picker, and the other 16, any custom colors ; you want to set. Empty values can be set to 0. ; ; Returns an array of 17 colors, $array[0] being the color "picked", and the other 16, ; any custom colors the user may have chosen. You can, of course, store these and then ; send them back to the color picker the next time it is called. At last! Store them ; in an ini file or wimilar and use them after next launch. ; ; NOTE: This function accepts and returns AutoIt RGB colors. If you need to convert to ; and from other color values, use ConvertColorValue(above) ; func ColorChooser($CustomColors=0, $hWndOwnder=0) if not IsArray($CustomColors) or Ubound($CustomColors) < 17 then $CustomColors = StringSplit("0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", ",", 2) endif local $ret_array[17], $color_picked, $aResult local $custcolors = "int ccolors[16]" local $col_STRUCT = "dword Size;hwnd hWndOwnder;handle hInstance;dword rgbResult;ptr CustColors;dword Flags;lparam lCustData;ptr lpfnHook;ptr lpTemplateName" local $tChoose = DllStructCreate($col_STRUCT) local $tcc = DllStructCreate($custcolors) $CustomColors[0] = '0x' & StringMid($CustomColors[0], 7, 2) & StringMid($CustomColors[0], 5, 2) & StringMid($CustomColors[0], 3, 2) DllStructSetData($tChoose, "Size", DllStructGetSize($tChoose)) DllStructSetData($tChoose, "hWndOwnder", $hWndOwnder) DllStructSetData($tChoose, "rgbResult", $CustomColors[0]) DllStructSetData($tChoose, "CustColors", DllStructGetPtr($tcc)) DllStructSetData($tChoose, "Flags", BitOR($__MISCCONSTANT_CC_ANYCOLOR, $__MISCCONSTANT_CC_FULLOPEN, $__MISCCONSTANT_CC_RGBINIT)) for $i = 1 to 16 ; set the custom colors.. $ccolor = Dec(StringMid($CustomColors[$i], 7, 2) & StringMid($CustomColors[$i], 5, 2) & StringMid($CustomColors[$i], 3, 2)) DllStructSetData($tcc, "ccolors", $ccolor, $i) next $aResult = DllCall("comdlg32.dll", "bool", "ChooseColor", "struct*", $tChoose) if ($aResult[0] == 0) then return SetError(-3, -3, -1) if @error then return SetError(@error, @extended, -1) $color_picked = Hex(String(DllStructGetData($tChoose, "rgbResult")), 6) if $color_picked < 0 then return SetError(-4, -4, -1) $ret_array[0] = '0x' & StringMid($color_picked, 5, 2) & StringMid($color_picked, 3, 2) & StringMid($color_picked, 1, 2) for $i = 1 to 16 ; create custom color array for return $cc = Hex(DllStructGetData($tcc, "ccolors", $i), 6) $ret_array[$i] = '0x' & StringMid($cc, 5, 2) & StringMid($cc, 3, 2) & StringMid($cc, 1, 2) next return $ret_array endfunc #cs ; a full implementation.. ; to store any system picked custom colors.. global $MyColors[17] = [""] ; System Color Picker.. func HotKeySystemPicker() SystemPicker($current_color) endfunc func SystemPicker($color) UnSetHotKeys() LoadCustomColors() $MyColors[0] = '0x' & $color $ret_colors = ColorChooser($MyColors, $MyGUI) if @error then return false switch $ret_colors[0] case -1, -3, -4, "" SetHotKeys() return false case else $MyColors = $ret_colors $new_color = StringTrimLeft($MyColors[0], 2) SaveCustomColors() SetHotKeys() endswitch endfunc func SaveCustomColors() if not IsArray($MyColors) or UBound($MyColors) < 17 then return false local $color_str for $i = 1 to 16 $color_str &= $MyColors[$i] & "," next $color_str = StringTrimRight($color_str, 1) if IniWrite($cpc_ini_path, $cpc_my_name, "custom_colors", $color_str) then return true endfunc func LoadCustomColors() local $color_str = IniRead($cpc_ini_path, $cpc_my_name, "custom_colors", "") $MyColors = StringSplit($color_str, ",") endfunc #ce